// test_BusCMDData_proc.c

#include "unity.h"
#include "command_proc.h"

// Include any other necessary headers
#include <string.h>

// Test variables
B1553_BusService testBusService;

void setUp(void)
{
    // Initialize the test structure before each test
    memset(&testBusService, 0, sizeof(B1553_BusService));
}

void tearDown(void)
{
    // Clean up after each test (if needed)
}

/**
 * Test case 1: Current mode is IDLE, setting to TEST mode
 * Expected: Successfully set mode with no error
 */
void test_BusCMDData_proc_WhenCurrentModeIsIdle_AndSettingToTestMode_ShouldSetModeSuccessfully(void)
{
    // Arrange
    testBusService.Telemeter_TX_Data.Work_Mode_Flag = SYS_MODE_IDLE;
    testBusService.TC_CmdData.paraID1 = SYS_MODE_TEST;
    
    // Act
    u32 result = _BusCMDData_proc(&testBusService);
    
    // Assert
    TEST_ASSERT_EQUAL(SYS_MODE_TEST, testBusService.Telemeter_TX_Data.Work_Mode_Flag);
    TEST_ASSERT_EQUAL(SYS_MODE_TEST, testBusService.Telemeter_TX_Data.Comm_Control_Flag);
    TEST_ASSERT_EQUAL(0, testBusService.Telemeter_TX_Data.Comm_Error_Flag);
    TEST_ASSERT_EQUAL(CMDHANDLE_BUSCMD, result);
}

/**
 * Test case 2: Current mode is WORK, trying to set to UPDATE mode
 * Expected: Reject setting and return error
 */
void test_BusCMDData_proc_WhenCurrentModeIsWork_AndSettingToUpdateMode_ShouldRejectAndReturnError(void)
{
    // Arrange
    testBusService.Telemeter_TX_Data.Work_Mode_Flag = SYS_MODE_WORK;
    testBusService.TC_CmdData.paraID1 = SYS_MODE_UPDATE;
    
    // Act
    u32 result = _BusCMDData_proc(&testBusService);
    
    // Assert
    TEST_ASSERT_EQUAL(SYS_MODE_WORK, testBusService.Telemeter_TX_Data.Work_Mode_Flag); // Mode should not change
    TEST_ASSERT_EQUAL(SYS_MODE_UPDATE, testBusService.Telemeter_TX_Data.Comm_Control_Flag);
    TEST_ASSERT_EQUAL(TELEMETRY_BUSCMD_TIMING_ERR, testBusService.Telemeter_TX_Data.Comm_Error_Flag);
    TEST_ASSERT_EQUAL(CMDHANDLE_DONE, result);
}

/**
 * Test case 3: Current mode is IDLE, setting to IDLE mode
 * Expected: Successfully set mode with no error
 */
void test_BusCMDData_proc_WhenCurrentModeIsIdle_AndSettingToIdleMode_ShouldSetModeSuccessfully(void)
{
    // Arrange
    testBusService.Telemeter_TX_Data.Work_Mode_Flag = SYS_MODE_IDLE;
    testBusService.TC_CmdData.paraID1 = SYS_MODE_IDLE;
    
    // Act
    u32 result = _BusCMDData_proc(&testBusService);
    
    // Assert
    TEST_ASSERT_EQUAL(SYS_MODE_IDLE, testBusService.Telemeter_TX_Data.Work_Mode_Flag);
    TEST_ASSERT_EQUAL(SYS_MODE_IDLE, testBusService.Telemeter_TX_Data.Comm_Control_Flag);
    TEST_ASSERT_EQUAL(0, testBusService.Telemeter_TX_Data.Comm_Error_Flag);
    TEST_ASSERT_EQUAL(CMDHANDLE_BUSCMD, result);
}

/**
 * Test case 4: Current mode is TEST, setting to IDLE mode
 * Expected: Successfully set mode with no error (switching from non-IDLE to IDLE is allowed)
 */
void test_BusCMDData_proc_WhenCurrentModeIsTest_AndSettingToIdleMode_ShouldSetModeSuccessfully(void)
{
    // Arrange
    testBusService.Telemeter_TX_Data.Work_Mode_Flag = SYS_MODE_TEST;
    testBusService.TC_CmdData.paraID1 = SYS_MODE_IDLE;
    
    // Act
    u32 result = _BusCMDData_proc(&testBusService);
    
    // Assert
    TEST_ASSERT_EQUAL(SYS_MODE_IDLE, testBusService.Telemeter_TX_Data.Work_Mode_Flag);
    TEST_ASSERT_EQUAL(SYS_MODE_IDLE, testBusService.Telemeter_TX_Data.Comm_Control_Flag);
    TEST_ASSERT_EQUAL(0, testBusService.Telemeter_TX_Data.Comm_Error_Flag);
    TEST_ASSERT_EQUAL(CMDHANDLE_BUSCMD, result);
}

/**
 * Test case 5: Invalid command parameter
 * Expected: Set error flag and return CMDHANDLE_DONE
 */
void test_BusCMDData_proc_WhenInvalidCommandParameter_ShouldSetErrorFlagAndReturnDone(void)
{
    // Arrange
    testBusService.Telemeter_TX_Data.Work_Mode_Flag = SYS_MODE_IDLE;
    testBusService.TC_CmdData.paraID1 = 25; // Invalid parameter
    
    // Act
    u32 result = _BusCMDData_proc(&testBusService);
    
    // Assert
    TEST_ASSERT_EQUAL(SYS_MODE_IDLE, testBusService.Telemeter_TX_Data.Work_Mode_Flag); // Mode should not change
    TEST_ASSERT_EQUAL(25, testBusService.Telemeter_TX_Data.Comm_Control_Flag);
    TEST_ASSERT_EQUAL(TELEMETRY_BUSCMD_UNDEFINE_ERR, testBusService.Telemeter_TX_Data.Comm_Error_Flag);
    TEST_ASSERT_EQUAL(CMDHANDLE_DONE, result);
}

/**
 * Test case 6: Test all valid mode settings
 * Expected: All valid modes should be correctly set
 */
void test_BusCMDData_proc_WhenSettingAllValidModes_ShouldSetEachModeSuccessfully(void)
{
    // Arrange
    u32 valid_modes[] = {SYS_MODE_IDLE, SYS_MODE_TEST, SYS_MODE_UPDATE, SYS_MODE_WORK};
    int mode_count = sizeof(valid_modes) / sizeof(valid_modes[0]);
    
    for (int i = 0; i < mode_count; i++) {
        // Reset test structure
        memset(&testBusService, 0, sizeof(B1553_BusService));
        testBusService.Telemeter_TX_Data.Work_Mode_Flag = SYS_MODE_IDLE; // Current mode is IDLE
        testBusService.TC_CmdData.paraID1 = valid_modes[i];              // Set to valid mode
        
        // Act
        u32 result = _BusCMDData_proc(&testBusService);
        
        // Assert
        TEST_ASSERT_EQUAL(valid_modes[i], testBusService.Telemeter_TX_Data.Work_Mode_Flag);
        TEST_ASSERT_EQUAL(valid_modes[i], testBusService.Telemeter_TX_Data.Comm_Control_Flag);
        TEST_ASSERT_EQUAL(0, testBusService.Telemeter_TX_Data.Comm_Error_Flag);
        TEST_ASSERT_EQUAL(CMDHANDLE_BUSCMD, result);
    }
}